"""
Case Type   : 系统内部使用工具
Case Name   : failover后原有数据是否损坏
Create At   : 2021/01/20
Owner       : opentestcase015
Description :
    1.主机执行事务
    2.关闭主数据库(主机执行)
    3.在备机上执行failover（备机执行）
    4.执行refrashconf进行信息写入
    5.重启集群
    6.检查主备是否切换成功
    7.查询事务是否存在
    8.环境恢复
Expect      :
    1.主机执行事务成功
    2.关闭主数据库成功
    3.在备机上执行failover成功
    4.执行refrashconf进行信息写入成功
    5.重启集群成功
    6.主备切换成功
    7.事务存在
    8.成功
History     :
    2022-6-15 opentestcase042 优化用例，判断重启后状态不正常后，增加重启步骤
    Modified by lopentestcase027 2023/1/13: 优化用例步骤格式及一主两备判断方式
"""

import unittest
import os
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro

LOG = Logger()
primary_sh = CommonSH('PrimaryDbUser')


@unittest.skipIf(3 != primary_sh.get_node_num(), '非1+2环境不执行')
class SystemInternalTools(unittest.TestCase):
    def setUp(self):
        LOG.info(f'-----{os.path.basename(__file__)} start-----')
        self.constant = Constant()
        self.PrimaryNode = Node('PrimaryDbUser')
        self.sh_primary = CommonSH('PrimaryDbUser')
        self.StandbyNode = Node('Standby1DbUser')
        self.sh_standby = CommonSH('Standby1DbUser')
        self.t_name = 't_gs_ctl_0073'

    def test_system_internal_tools(self):
        LOG.info('--------step1:主机执行事务   expect: 成功--------')
        msg = self.sh_primary.execut_db_sql(
            f'create table {self.t_name} (a integer);')
        LOG.info(msg)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS, msg)

        LOG.info('--------step2:关闭主数据库   expect: 成功--------')
        stop_msg = self.sh_primary.stop_db_instance()
        self.assertIn(self.constant.GS_CTL_STOP_SUCCESS_MSG, stop_msg)

        LOG.info('--------step3:failover备升主  expect: 成功--------')
        excute_msg = self.sh_standby.execute_gsctl(
            "failover", self.constant.FAILOVER_SUCCESS_MSG, param="-m fast")
        self.assertTrue(excute_msg)

        LOG.info('-------step4:进行refreshconf信息写入  expect: 成功--------')
        excute_msg = self.sh_standby.exec_refresh_conf()
        self.assertTrue(excute_msg)

        LOG.info('-------step5:重启集群           expect: 成功--------')
        self.sh_primary.restart_db_cluster()
        status = self.sh_primary.get_db_cluster_status(param='detail')
        self.assertIn(self.constant.CLUSTER_NORMAL_MSG, status)

        LOG.info('-------step6:查看主备状态切换     expect: 切换成功-------')
        status = self.sh_primary.get_db_cluster_status(param='detail')
        self.assertIn('S Primary Normal', status)

        LOG.info('-------step7:查询事务     expect: 事务存在-------')
        msg = self.sh_primary.execut_db_sql(
            f'select count(*) from {self.t_name};')
        LOG.info(msg)
        self.assertIn('0', msg)

    def tearDown(self):
        LOG.info('--------step8:环境恢复    expect:成功---------')
        node_msg = self.sh_standby.get_db_cluster_status(param='detail')
        LOG.info(node_msg)
        if 'S Primary Normal' in node_msg:
            LOG.info('--------------恢复主备状态--------------')
            recover_cmd = f'''source {macro.DB_ENV_PATH};
                gs_ctl switchover -D {macro.DB_INSTANCE_PATH} -m fast;
                gs_om -t refreshconf;
                '''
            LOG.info(recover_cmd)
            recover_msg = self.PrimaryNode.sh(recover_cmd).result()
            LOG.info(recover_msg)
        else:
            return '主备节点正常'
        msg = self.sh_primary.execut_db_sql(f'drop table if exists '
                                            f'{self.t_name};')
        LOG.info(msg)
        status = self.sh_primary.get_db_cluster_status(param='detail')
        self.assertIn(self.constant.CLUSTER_NORMAL_MSG, status)
        LOG.info(f'--------{os.path.basename(__file__)} end--------')
